home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / pascal / tppop16.zip / UNHOOK.PAS < prev    next >
Pascal/Delphi Source File  |  1988-09-28  |  4KB  |  149 lines

  1. {$R-,S-,I+,D+,T+,F-,V-,B-,N-,L+ }
  2. Unit Unhook;
  3.  
  4. { Copyright (c)1988 Ross Neilson Wentworth                           }
  5. {                   Serendipity Software                             }
  6. {                   1422 Elkgrove Circle, #3                         }
  7. {                   Venice, CA  90291                                }
  8. { All Rights Reserved                                                }
  9.  
  10. { This unit provides almost everything that is necessary to remove a }
  11. { resident program from memory.  Examine the provided example NODICE }
  12. { to see how easy it is to use.                                      }
  13.  
  14. Interface
  15.  
  16. Uses Dos;
  17.  
  18. Function Installed(MultId : Byte) : Boolean;
  19.  
  20. { Returns true if the resident program with the matching I.D. is loaded. }
  21.  
  22. Function  OkToRemove(MultID : Byte) : Boolean;
  23.  
  24. { Returns true if it is safe to unload the resident }
  25. { program with the matching I.D. number.            }
  26.  
  27. Procedure RemoveProgram(MultID : Byte);
  28.  
  29. { Removes the program with the matching I.D. from memory. }
  30.  
  31. Implementation
  32.  
  33. Type
  34.   VectorTable = Record
  35.                   Number : Byte;
  36.                   OldInt : Pointer;
  37.                   Offset : Word;
  38.                 End;
  39.   VectorArray = Array[1..2] of VectorTable;
  40.   VectorPtr = ^VectorArray;
  41.  
  42. Function DosVersion : Word;
  43.  
  44. { Returns the DOS version as a word.  It swaps the two bytes }
  45. { to make test more logical, i.e. DosVersion < $0300 }
  46.  
  47.   InLine($B4/$30/    { mov   ah,30h  }
  48.          $CD/$21/    { int   21h     }
  49.          $86/$E0);   { xchg  ah,al   }
  50.  
  51. Function CheckSignature(MultId : Byte) : Byte;
  52.  
  53. { Returns the popup's code segment }
  54.  
  55.   InLine($58/       { pop    ax    }
  56.          $88/$C4/   { mov    ah,al }
  57.          $B0/$00/   { mov    al,0  }
  58.          $CD/$2F);  { int    2Fh   }
  59.  
  60. Function GetTable(MultId : Byte) : Pointer;
  61.  
  62. { Returns a pointer to the vector table }
  63.  
  64.   InLine($58/       { pop    ax    }
  65.          $88/$C4/   { mov    ah,al }
  66.          $B0/$01/   { mov    al,1  }
  67.          $CD/$2F);  { int    2Fh   }
  68.  
  69. Function GetCseg(MultId : Byte) : Word;
  70.  
  71. { Returns the popup's code segment }
  72.  
  73.   InLine($58/       { pop    ax    }
  74.          $88/$C4/   { mov    ah,al }
  75.          $B0/$02/   { mov    al,2  }
  76.          $CD/$2F);  { int    2Fh   }
  77.  
  78. Procedure ReleaseMemory(MultId : Byte);
  79.  
  80. { Releases the popup's memory }
  81.  
  82.   InLine($58/       { pop    ax    }
  83.          $88/$C4/   { mov    ah,al }
  84.          $B0/$03/   { mov    al,3  }
  85.          $CD/$2F);  { int    2Fh   }
  86.  
  87. Function Installed(MultID : Byte) : Boolean;
  88.  
  89. Var
  90.   TempV : Pointer;
  91.  
  92. Begin
  93.   Installed := False;
  94.   If DosVersion < $0300 Then
  95.   Begin               { DOS 2.x }
  96.     GetIntVec($2F,TempV);
  97.     If TempV = Nil Then Exit;
  98.   End;
  99.   If CheckSignature(MultId) = $FF Then Installed := True;
  100. End;
  101.  
  102. Function  OkToRemove(MultID : Byte) : Boolean;
  103.  
  104. Var
  105.   OldVector : Pointer;
  106.   NewVector : Pointer;
  107.   Index  : Integer;
  108.   PopCSeg : Word;
  109.   Table : VectorPtr;
  110.  
  111. Begin
  112.   Table := GetTable(MultId);
  113.   Index := 1;
  114.   OkToRemove := False;
  115.   PopCSeg := GetCSeg(MultId);
  116.   While Table^[Index].Number <> 0 Do
  117.  
  118.   { compares the current value of the interrupt vector with what the  }
  119.   { resident program set it to.  If ALL of them are unchanged then it }
  120.   { is safe to remove the program from memory.                        }
  121.  
  122.   Begin
  123.     GetIntVec(Table^[Index].Number,NewVector);
  124.     OldVector := Ptr(PopCSeg,Table^[Index].Offset);
  125.     If OldVector <> NewVector Then Exit;
  126.     Inc(Index);
  127.   End;
  128.   OkToRemove := True;
  129. End;
  130.  
  131. Procedure RemoveProgram(MultID : Byte);
  132.  
  133. Var
  134.   Index   : Integer;
  135.   Table   : VectorPtr;
  136.  
  137. Begin
  138.   ReleaseMemory(MultID);              { release the memory }
  139.   Table := GetTable(MultId);
  140.   Index := 1;
  141.   While Table^[Index].Number <> 0 Do  { restore the interrupt vectors }
  142.   Begin
  143.     SetIntVec(Table^[Index].Number,Table^[Index].OldInt);
  144.     Inc(Index);
  145.   End;
  146. End;
  147.  
  148. End.
  149.